package com.gitee.sop.layui.adminserver.module.background.develop.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gitee.sop.layui.adminserver.module.background.develop.dto.SysFunctionDTO;
import com.gitee.sop.layui.adminserver.module.background.develop.entity.SysFunction;
import com.gitee.sop.layui.adminserver.module.background.develop.entity.SysFunctionRole;
import com.gitee.sop.layui.adminserver.module.background.develop.manager.SysFunctionCacheManager;
import com.gitee.sop.layui.adminserver.module.background.develop.mapper.SysFunctionMapper;
import com.gitee.sop.layui.adminserver.module.background.develop.service.SysFunctionRoleRelationService;
import com.gitee.sop.layui.adminserver.module.background.develop.service.SysFunctionRoleService;
import com.gitee.sop.layui.adminserver.module.background.develop.service.SysFunctionService;
import com.gitee.sop.layui.adminserver.module.background.develop.util.SysFunctionUtil;
import com.gitee.sop.layui.adminserver.module.background.develop.vo.SysFunctionTreeTableVo;
import com.gitee.sop.layui.adminserver.module.base.bo.ZTreeNode;
import com.gitee.sop.layui.adminserver.module.base.error.ServiceInterruptionException;
import com.gitee.sop.layui.adminserver.module.base.util.AssertUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 系统功能 记录系统所有的功能列表，并提供功能是否权限才能访问 服务实现类
 * </p>
 *
 * @author admin
 * @since 2019-11-13
 */
@Service
public class SysFunctionServiceImpl extends ServiceImpl<SysFunctionMapper, SysFunction> implements SysFunctionService {

    @Lazy
    @Resource
    private SysFunctionRoleRelationService sysAdminFunctionRoleRelationService;
    @Lazy
    @Resource
    private SysFunctionRoleService sysFunctionRoleService;
    @Lazy
    @Autowired
    private SysFunctionCacheManager sysFunctionCacheManager;

    @Override
    public List<ZTreeNode> searchTreeList() {
        return SysFunctionUtil.toZTreeNode(sysFunctionCacheManager.listAll(), baseMapper.selectMaxId());
    }

    @Override
    public List<SysFunctionTreeTableVo> searchTreeTableList() {
        return SysFunctionUtil.toSysFunctionTreeTableVo(sysFunctionCacheManager.listAll(), baseMapper.selectMaxId());
    }

    @Override
    public void updateBatchById(Integer[] ids, SysFunctionDTO query) {
        List<SysFunction> list = new ArrayList<>(ids.length);
        for (int i = 0; i < ids.length; ++i) {
            SysFunction sysFunction = new SysFunction();
            sysFunction.setId(ids[i]);
            if (query.getStatus() != null) {
                sysFunction.setStatus(query.getStatus());
            }
            if (query.getPermissionSymbol() != null) {
                sysFunction.setPermissionSymbol(query.getPermissionSymbol());
            }
            list.add(sysFunction);
        }

        sysFunctionCacheManager.updateBatchByIds(list);
    }

    @Override
    public List<ZTreeNode> searchTreeList(Integer functionRoleId) {
        SysFunctionRole sysFunctionRole = sysFunctionRoleService.getById(functionRoleId);
        AssertUtil.notNull(sysFunctionRole, ServiceInterruptionException.fail(400, "角色不存在"));
        List<SysFunction> list;
        //获取可见功能
        if (sysFunctionRole.getPid() == 0) {
            list = list();
        } else {
            list = baseMapper.selectListByRoleId(sysFunctionRole.getPid());
            AssertUtil.notEmpty(list, ServiceInterruptionException.fail(400, "无可用功能，请设置上级角色功能权限"));
        }

        List<Integer> functionIdList = sysAdminFunctionRoleRelationService.listFunctionIdByFunctionRoleId(functionRoleId);

        List<ZTreeNode> zTreeNodeList = SysFunctionUtil.toZTreeNode(list, baseMapper.selectMaxId());
        //设置选择
        zTreeNodeList.forEach(zTreeNode -> {
            if (functionIdList.contains(zTreeNode.getId())) {
                zTreeNode.setChecked(true);
            }
        });
        return zTreeNodeList;
    }

    @Override
    public SysFunction getOneByFullUri(String fullUri) {
        List<SysFunction> sysFunctionList = sysFunctionCacheManager.listAll();
        for (SysFunction sysFunction : sysFunctionList) {
            String[] fullUriArray = sysFunction.getFullUri().split(",");
            for (String s : fullUriArray) {
                if (matchUri(fullUri, s)) {
                    return sysFunction;
                }
            }
        }
        return null;
    }

    @Override
    public List<SysFunction> selectAllInId(List<Integer> functionIdList) {
        List<SysFunction> list = new ArrayList<>();
        sysFunctionCacheManager.listAll().forEach(sysFunction -> {
            if (functionIdList.contains(sysFunction.getId())) {
                list.add(sysFunction);
            }
        });
        return list;
    }

    /**
     * 匹配uri
     *
     * @param requestUri  请求uri
     * @param originalUri 源uri
     * @return
     */
    private boolean matchUri(String requestUri, String originalUri) {
        if (originalUri.indexOf("{") != -1) {
            String[] requestUriArray = requestUri.split("/");
            String[] originalUriArray = originalUri.split("/");
            //层级不等，必不是相同uri
            if (requestUriArray.length != originalUriArray.length) {
                return false;
            }
            for (int i = 0; i < originalUriArray.length; ++i) {
                int start = originalUriArray[i].indexOf("{");
                int end = originalUriArray[i].indexOf("}");
                if (start != -1 && end != -1 && start < end) {
                    continue;
                }
                if (!requestUriArray[i].equals(originalUriArray[i])) {
                    return false;
                }
            }
            return true;
        }
        return requestUri.equals(originalUri);
    }
}
